<?php
/*******************************************************************************
classManager.class.php

Created by Kathy Washington (kawashi@emory.edu)
Modified by NCSU Libraries, NC State University. Modifications by Karl Doerr and Troy Hurteau (libraries.opensource@ncsu.edu).

This file is part of NCSU's distribution of ReservesDirect. This version has not been downloaded from Emory University
or the original developers of ReservesDirect. Neither Emory University nor the original developers of ReservesDirect have authorized
or otherwise endorsed or approved this distribution of the software.

Copyright (c) 2004-2006 Emory University, Atlanta, Georgia.

Licensed under the NCSU ReservesDirect License, Version 2.0 (the "License"); 
you may not use this file except in compliance with the License. You may obtain a copy of the full License at
 http://www.lib.ncsu.edu/it/opensource/

ReservesDirect is distributed in the hope that it will be useful,
but is distributed "AS IS" and WITHOUT ANY WARRANTY, without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE, and without any warranty as to non-infringement of any third
party's rights. See the License for the specific language governing permissions and limitations under the License.

The original version of ReservesDirect is located at:
http://www.reservesdirect.org/

This version of ReservesDirect, distributed by NCSU, is located at:
http://code.google.com/p/reservesdirect-ncsu/

*******************************************************************************/
require_once(APPLICATION_PATH . '/common.inc.php');
require_once(APPLICATION_PATH . '/classes/users.class.php');
require_once(APPLICATION_PATH . '/displayers/classDisplayer.class.php');
require_once(APPLICATION_PATH . '/displayers/mobileClassDisplayer.class.php');
require_once(APPLICATION_PATH . '/managers/copyClassManager.class.php');

require_once(APPLICATION_PATH . '/lib/Rd/Department.php');
require_once(APPLICATION_PATH . '/lib/Rd/User.php');
require_once(APPLICATION_PATH . '/lib/Rd/Course.php');
require_once(APPLICATION_PATH . '/lib/Rd/Course/Instance.php');
require_once(APPLICATION_PATH . '/lib/Rd/Course/Alias.php');
require_once(APPLICATION_PATH . '/lib/Rd/Term.php');

class classManager extends Rd_Manager_Base
{
	public $user;
	public $displayClass;
	public $displayFunction;
	public $argList;
	
	function __construct($cmd, $request, $user)
	{
		$u = Account_Rd::getUserInterface();
		$this->displayClass = (
			Rd_Layout::isMobile()
			? 'mobileClassDisplayer'
			: 'classDisplayer'
		);

		//otherwise proceed down the path of good intentions
        global $g_permission, $ci;
		
		//set the page (tab)
		if($u->getRole() >= $g_permission['staff']) {
			$this->_setTab('manageClasses');
		} else {
			$this->_setTab('myReserves');
		}

		switch ($cmd)
		{			
			case 'removeClass':	//remove classes from a user's list (deletes access entry)
				$this->_setLocation('leave a class');
				Rd_Help::setDefaultArticleId(27);
				$leave = $u->getDefaultRole() < Account_Rd::LEVEL_FACULTY || array_key_exists('asStudent', $_REQUEST);
				if(!empty($_REQUEST['ci'])) {	//user selected class
					$ci = new courseInstance($_REQUEST['ci']);
					$ci->getCourseForUser();
					if(!$leave) {	//trying to remove a class the user is teaching
						$u->removeClass($ci->course->getCourseAliasID());						
					}
					else {	//trying to leave a class the user is enrolled in	
						$u->leaveClass($ci->course->getCourseAliasID());
					}
					
					//go to course listing
					$this->_delegateManager = new classManager('viewCourseList', array(), $u);
				}
				else {	//show class list					
					if(!$leave) {
						//for instructors this will be a list of cancelled/inactive courses they are teaching
						$course_instances = $u->getCourseInstancesToRemove();
						$type = 'instructor';
					}
					else {
						//for students this will be a list of all courses in which they are enrolled (except autofed)
						$course_instances = $u->getCourseInstancesToLeave();
						$type = '';
					}

					$msg = (
						$leave
						? 'Select a class to leave:'
						: 'Select a class to remove:'
					);
						
					$this->displayFunction = 'displaySelectClass';
					$this->argList = array('removeClass', $course_instances, $msg, array('type'=>$type), true);
				}				
			break;
	
			
			case 'activateClass':
				if(empty($_REQUEST['ci'])) {
					return false;
				}
				
				//just need to change the class status to active
				$ci = new courseInstance($_REQUEST['ci']);
				$ci->setStatus('ACTIVE');
				
				//show success screen
				$this->displayFunction = 'displayActivateSuccess';
				$this->argList = array($ci->getCourseInstanceID());			
			break;
			
			case 'deactivateClass':
				$u = Rd_Registry::get('root:userInterface');
				if(empty($_REQUEST['ci'])) {
					return false;
				}
				
				//just need to change the class status to active
				$ci = new courseInstance($_REQUEST['ci']);
				$ci->setStatus('AUTOFEED');
				
				//go to course listing
				$this->_delegateManager = new classManager('viewCourseList', array(), $u);
			break;	

			case 'editInstructors':
				$this->_setLocation('edit instructors');
				Rd_Help::setDefaultArticleId(12);
				
				$ci = new courseInstance($_REQUEST['ci']);
				$ci->getPrimaryCourse();
				try{
					$ci->getCrossListings();  //load cross listings	
				} catch (Rd_Exception $e) {
					
				}	

				if (
					array_key_exists('addInstructor', $_REQUEST) 
					&& $_REQUEST['addInstructor']
				) {
					$ci->addInstructor($ci->primaryCourseAliasID, (int)$_REQUEST['instructor']); //Add instructor to primary course alias
					for ($i=0; $i<count($ci->crossListings); $i++) {
						$ci->addInstructor($ci->crossListings[$i]->courseAliasID, (int)$_REQUEST['instructor']); // add instructor to the Xlistings
					}		
					
				}

				if (array_key_exists('removeInstructor', $_REQUEST) && $_REQUEST['removeInstructor']) {
					//Problem - Should there be a stipulation that you can't remove the last instructor?
					$instructors = $_REQUEST['Instructor'];

					if (is_array($instructors) && !empty($instructors)){
						foreach($instructors as $instructorID)
						{
							$ci->removeInstructor($ci->primaryCourseAliasID,$instructorID); //remove instructor from primary course alias
							for ($i=0; $i<count($ci->crossListings); $i++) {
								$ci->removeInstructor($ci->crossListings[$i]->courseAliasID, $instructorID); // remove instructor from the Xlistings
							}
						}
					}
				}

				$ci->getInstructors(); //load current instructors
				//$ci->getCourseForInstructor($user->getUserID());
				$ci->getPrimaryCourse();
				//$instructorList = common_getUsers('instructor'); //get instructors to populate drop down box				
				$this->displayFunction = 'displayEditInstructors';
				$this->argList = array($ci, 'ADD AN INSTRUCTOR', 'Choose an Instructor', 'Instructor', 'CURRENT INSTRUCTORS', 'Remove Selected Instructors', $request);
			break;

			case 'editProxies':
				$this->_setLocation('edit proxies');
				Rd_Help::setDefaultArticleId(13);
				
				$ci = new courseInstance($_REQUEST['ci']);
				$ci->getPrimaryCourse();
				try{
					$ci->getCrossListings();  //load cross listings	
				} catch (Rd_Exception $e) {
					
				}	
				

				if (isset($_REQUEST['addProxy'])) {
					$user->makeProxy($_REQUEST['proxy'],$ci->courseInstanceID);
					/*
					$ci->addProxy($ci->primaryCourseAliasID,$_REQUEST['prof']); //Add proxy to primary course alias
					for ($i=0; $i<count($ci->crossListings); $i++) {
						$ci->addProxy($ci->crossListings[$i]->courseAliasID, $_REQUEST['prof']); // add proxy to the Xlistings
					}
					*/
				}

				if (isset($_REQUEST['removeProxy'])) {
					$proxies = $_REQUEST['proxies'];

					if (is_array($proxies) && !empty($proxies)){
						foreach($proxies as $proxyID)
						{
							$user->removeProxy($proxyID, $ci->courseInstanceID);
							/*
							$ci->removeProxy($ci->primaryCourseAliasID,$proxyID); //remove proxy from primary course alias
							for ($i=0; $i<count($ci->crossListings); $i++) {
								$ci->removeProxy($ci->crossListings[$i]->courseAliasID, $proxyID); // remove proxy from the Xlistings
							}
							*/
						}
					}
				}

				$ci->getProxies(); //load current proxies
				$ci->getPrimaryCourse();

				if (isset($_REQUEST['queryText']) &&  $_REQUEST['queryText'] != "")
				{
					$usersObj = new users();
					$usersObj->search($_REQUEST['queryTerm'], $_REQUEST['queryText']);  //populate userList
				}

				//$ci->getCourseForInstructor($user->getUserID());
				//$instructorList = common_getUsers('proxy'); //get instructors to populate drop down box

				$this->displayFunction = 'displayEditProxies';
				$this->argList = array($ci, (isset($usersObj) && isset($usersObj->userList) ? $usersObj->userList : null), $_REQUEST);
			break;
			
			case 'copyItems':
				$this->_setLocation('copy reserve items to another class');
				Rd_Help::setDefaultArticleId(20);
				
				$class_list = $user->getCourseInstancesToEdit();
				$this->displayFunction = 'displaySelectClass';
				$this->argList = array('processCopyItems', $class_list, 'Select class to copy TO:', $request);
			break;
			
			case 'processCopyItems':
				$this->_setLocation('copy reserve items to another class');

				$srcCI = new courseInstance($_REQUEST['originalClass']);
				//copy reserves
				if(is_array($_REQUEST['reservesArray']) && !empty($_REQUEST['reservesArray'])) {
					$srcCI->copyReserves($_REQUEST['ci'], $_REQUEST['reservesArray']);
				}
				
				$dstCI = new courseInstance($_REQUEST['ci']);
				$srcCI->getPrimaryCourse();
				$dstCI->getPrimaryCourse();
			
				$this->displayFunction = 'displayCopyItemsSuccess';
				$this->argList = array($dstCI,$srcCI,count($_REQUEST['reservesArray']));
				break;
			default:
				$with = (array('960css'));
				return parent::__construct($cmd, $request, $with);
				break;	
		}	
	}
	
	public function indexAction($request = array())
	{
		$this->viewCourseListAction($request);
	}
	
	public function myReservesAction($request = array())
	{
		$this->viewCourseListAction($request);
	}
	
	public function viewCourseListAction($request = array())
	{
		$this->_setTab('myReserves');
		$this->_setLocation('home');
		$instructorCiList = array();
		$proxyCiList = array();
		$studentCiList = array();
		$activationDate = date('Y-m-d', strtotime('+1 year'));
		$expirationDate = date('Y-m-d');
		
		$studentCiList = $this->_user->getCourseInstances();
		
		if($this->_user->getDefaultRole() >= Account_Rd::LEVEL_FACULTY) {									
			$tmp = $this->_user->fetchCourseInstances(
				'instructor', $activationDate, $expirationDate, 'ACTIVE'
			);
			if(!empty($tmp)) {
				$instructorCiList['ACTIVE'] = $tmp;
			}
			$tmp = $this->_user->fetchCourseInstances(
				'instructor', $activationDate, $expirationDate, 'INACTIVE'
			);
			if(!empty($tmp)) {
				$instructorCiList['INACTIVE'] = $tmp;
			}					
			$tmp = $this->_user->fetchCourseInstances(
				'instructor', $activationDate, $expirationDate, 'AUTOFEED'
			);
			if(!empty($tmp)) {
				$instructorCiList['AUTOFEED'] = $tmp;
			}
			$tmp = $this->_user->fetchCourseInstances(
				'instructor', $activationDate, $expirationDate, 'CANCELED'
			);
			if(!empty($tmp)) {
				$instructorCiList['CANCELED'] = $tmp;
			}
	   	}
	   	
		if($this->_user->getDefaultRole() >= Account_Rd::LEVEL_PROXY) {									
			$proxyCiList = $this->_user->fetchCourseInstances(
				'proxy', $activationDate, $expirationDate, 'ACTIVE'
			);
			$proxyCiList = array_merge(
				$proxyCiList, 
				$this->_user->fetchCourseInstances(
					'proxy', $activationDate, $expirationDate, 'INACTIVE'
				)
			);
		}
		$this->displayFunction = "displayCourseList";
		$this->argList = array(
			$studentCiList, 
			$instructorCiList, 
			$proxyCiList
		);
	}
	
	public function manageClassesAction($request = array()) {
		$this->_setLocation('manage classes home');
		$this->displayFunction = 'displayStaffHome';
		$this->argList = array($this->_user);
	}
	
	public function addClassAction($request = array()) {
		$this->_setLocation('join a class');
		$this->with('jQueryUiAutocomplete');
		$this->with('noPrototype');
		Rd_Help::setDefaultArticleId(27);
		$ci = (
			array_key_exists('ci', $request)
			? $request['ci']
			: NULL
		);
		$ca = (
			array_key_exists('ca', $request)
			? $request['ca']
			: NULL
		);
		if (is_null($ca) && !is_null($ca)) {
			$courseInstance = new courseInstance($ci);
			$ca = $courseInstance->course->getCourseAliasID();
		}
		$instructorId = (
			Rd_Array::keyExistsAndNotBlank('searchInstructorResult', $request)
			? $request['searchInstructorResult']
			: NULL
		);
		$instructorSearch = (
			Rd_Array::keyExistsAndNotBlank('searchInstructor', $request)
			? $request['searchInstructor']
			: NULL
		);
		$instructorList = array();
		if (!is_null($instructorSearch)) {
			$users = new users();
			$userData = $users->search('any', trim($instructorSearch), Account_Rd::LEVEL_PROXY);
			if (count($userData) == 1 && is_null($instructorId)) {
				$instructorObject = array_shift($userData);
				if (is_a($instructorObject, 'user')) {
					$instructorId = $instructorObject->getId();
				}
			}
			foreach($userData as $user){
				$instructorList[$user->getUserID()] = 
					$user->getLastName() 
					. ', ' . $user->getFirstName() 
					. ' (' . $user->getUserName() . ')';
			}
		}
/*		$departmentId = (
			array_key_exists('departmentId', $request)
			? $request['departmentId']
			: NULL
		);*/
		$departmentSearch = (
			Rd_Array::keyExistsAndNotBlank('searchDepartment', $request)
			? $request['searchDepartment']
			: NULL
		);
		$disabledCi = array();
		$enrolledAndPendingCourses = $this->_user->getAllCourseInstances();
		foreach($enrolledAndPendingCourses as $courseInstance) {
			$disabledCi[] = $courseInstance->getId();
		}
		
		if (!is_null($ca)) {
			//$courseInstance = new courseInstance($ci);$courseInstance->course->getCourseAliasID();
			$course = new course($ca);
			if($course->isOpenEnrollment()) {
				$this->_user->joinClass($course->getCourseAliasID(), 'APPROVED');
				Rd_Layout::setMessage('generalAlert', 'You have added ' . $course->getStandardLabel() . ' to your list of reserve courses.');
			} else {	//else, add the student as pending
				$this->_user->joinClass($course->getCourseAliasID(), 'PENDING');
				Rd_Layout::setMessage('generalAlert', 'You have added ' . $course->getStandardLabel() 
					. ' to your list of reserve courses. This course requires instructor approval to join. '
					. 'You will have access to this course after it has been approved.');
			}
			$this->_delegateManager = new classManager('viewCourseList', $this->_user, NULL, NULL);
		} else {	//no class, find one
			if(Account_Rd::atLeastStaff()) {	//if staff, show ajax lookup
				//$this->displayFunction = 'displaySelectClass';
				//$this->argList = array('addClass', null, 'Select a class to add:');
				$courseList =
					Rd_Course::pickerSearchReady($request)
					? Rd_Course::pickerSearch($request)
					: array();
				$model = array(
					'showSearch' => TRUE,
					'formCommand' => 'addClass',
					'returnUrl' => './?cmd=viewCourseList',
					'courses' => $courseList,
					'termValue' => (array_key_exists('searchTerm', $request) ? $request['searchTerm'] : ''),
					'instructorFieldValue' => (array_key_exists('searchInstructor', $request) ? $request['searchInstructor'] : ''),
					'instructorValue' => (array_key_exists('searchInstructorResult', $request) ? $request['searchInstructorResult'] : ''),
					'departmentFieldValue' => (array_key_exists('searchDepartment', $request) ? $request['searchDepartment'] : ''),
					'courseFieldValue' => (array_key_exists('searchCourse', $request) ? $request['searchCourse'] : ''),
					'linkOn' => 'ca'
				);
				$this->setModel($model);
				$this->displayFunction = 'displayCoursePicker';
			} else if(!is_null($instructorId)) {
				$courseInstanceList = $this->_user->getCourseInstancesByInstr($instructorId);
				$courseList = array();
				foreach($courseInstanceList as $courseInstance) {
					$courses = $courseInstance->getCourses();
					foreach($courses as $course) {
						$courseList[] = $course; //$courseInstance->getPrimaryCourse();
					}
				}
				if (count($courseList) == 0) {
					$instructorObject = new instructor($instructorId);
					$instructorName = $instructorObject->getName();
					Rd_Layout::appendMessage('generalAlert', "There are no courses in the current sememster with reserves for {$instructorName}.");
					$this->displayFunction = 'displayCourseSearch';
					$this->argList = array(array(
						'instructorFieldValue' => $instructorSearch,
						//'instructorValue' => $instructorId, //don't propigate this, it dead ends the user
						'departmentFieldValue' => $departmentSearch,
						'instructorList' => $instructorList
					));
				} else {
					$model = array(
						'showSearch' => FALSE,
						'formCommand' => 'addClass',
						'returnUrl' => './?cmd=viewCourseList',
						'courses' => $courseList,
						'disabledCourseInstances' => $disabledCi,
						'linkOn' => 'ca'
					);
					$this->setModel($model);
					$this->displayFunction = 'displayCoursePicker';
				}
			}
			/*	elseif($department_id) {	//search by department
					$termsObj = new terms();	
					$current_term = $termsObj->getCurrentTerm();
					$usersObj = new users();
										
					$course_instances = $usersObj->searchForCI(null, $department_id, null, null, $current_term->getTermID());
				}
					
				//do not display courses with closed enrollment or inactive status						
				if (!empty($course_instances))
				{
					foreach($course_instances as $ci_x_index=>$ci_x) {
						if(!$ci_x->EnrollmentAllowed()) {								
							unset($course_instances[$ci_x_index]);
						}
					}
				}
								
				$msg = 'Select a class to add:';							
				$this->displayFunction = 'displaySelectClass';
				$this->argList = array('addClass', $course_instances, $msg);
			} */ 
			else if (!is_null($departmentSearch)) {
				if (strlen($departmentSearch) < 2) {
					Rd_Layout::appendMessage('generalAlert', "Please provide at least two characters for department search.");
					$this->displayFunction = 'displayCourseSearch';
					$this->argList = array(array(
						'departmentFieldValue' => $departmentSearch
					));
				} else {
					$request['searchTerm'] = Rd_Term::getCurrent()->getId();
					$request['searchStatus'] = 'ACTIVE';
					$courseList =
						Rd_Course::pickerSearchReady($request)
						? Rd_Course::pickerSearch($request)
						: array();
					if (count($courseList) > 0) {
						$model = array(
							'showSearch' => FALSE,
							'formCommand' => 'addClass',
							'returnUrl' => './?cmd=viewCourseList',
							'courses' => $courseList,
							'disabledCourseInstances' => $disabledCi,
							'linkOn' => 'ca'
						);
					$this->setModel($model);
					$this->displayFunction = 'displayCoursePicker';
					} else {
						$cleanDepartment = htmlentities($departmentSearch);
						Rd_Layout::appendMessage('generalAlert', "There are no courses in the current sememster with reserves for the department: {$cleanDepartment} .");
						$this->displayFunction = 'displayCourseSearch';
						$this->argList = array(array(
							'departmentFieldValue' => $departmentSearch
						));
					}
				}
			} else {	//need either instructorId or departmentSearch					
				$this->displayFunction = 'displayCourseSearch';
				$this->argList = array(array(
					'instructorFieldValue' => $instructorSearch,
					'instructorValue' => $instructorId,
					'departmentFieldValue' => $departmentSearch,
					'instructorList' => $instructorList
				));
			}
		}
	}
	
	public function createClassAction($request = array())
	{
		$this->with('jQueryUiAutocomplete');
		$this->with('noPrototype');
		$this->_setLocation('create new class');
		Rd_Help::setDefaultArticleId(25);
		$this->displayFunction = 'displayCreateClass';
		$submitted = array_key_exists('Submit', $request);
		$ci = Rd_Array::keyExistsAndNotBlank('ci', $request) 
			? $request['ci'] 
			: '';
		$courseInstanceObject = Rd_Course_Instance::getById($ci);
		$department = 
			Rd_Array::keyExistsAndNotBlank('department', $request) 
			? $request['department'] 
			: '';
		$departmentObject = Rd_Department::getById($department);
		$courseNumber = 
			Rd_Array::keyExistsAndNotBlank('courseNumber', $request) 
			? trim($request['courseNumber'])
			: '';
		$courseObject = Rd_Course::getByDeptIdAndCourseNumber($department, $courseNumber);
		$section = 	
			Rd_Array::keyExistsAndNotBlank('section', $request) 
			? trim($request['section'])
			: '';
		$providedCourseName = //#TODO handle course lookup to prevent duplicates
			Rd_Array::keyExistsAndNotBlank('courseName', $request) 
			? $request['courseName'] 
			: '';
		$term = 
			Rd_Array::keyExistsAndNotBlank('term', $request) 
			? $request['term'] 
			: '';
		$termObject = Rd_Term::getById($term);
		$activationDate = 
			Rd_Array::keyExistsAndNotBlank('activation_date', $request) 
			? $request['activation_date'] 
			: '';
		$expirationDate = 
			Rd_Array::keyExistsAndNotBlank('expiration_date', $request) 
			? $request['expiration_date'] 
			: '';
		$enrollment =
			Rd_Array::keyExistsAndNotBlank('enrollment', $request) 
			? $request['enrollment'] 
			: '';
		$instructor =
			Rd_Array::keyExistsAndNotBlank('searchInstructorResult', $request) 
			? $request['searchInstructorResult'] 
			: '';
		$instructorObject = Rd_User::getById($instructor);

		if ($submitted) {
			if (!$departmentObject) {
				Rd_Layout::setMessage('departmentMatchError', 'Unable to find the specified department.');
			}
			if (!$termObject) {
				Rd_Layout::setMessage('termMatchError', 'Unable to find the specified term.');
			}
			if (!$instructorObject) {
				Rd_Layout::setMessage('instructorMatchError', 'Unable to find the specified instructor.');
			}
		}
		$errorMessage = '';
		$valid = (
			$courseInstanceObject
			|| (
				$departmentObject
				&& $courseNumber
				&& $section
				&& $providedCourseName
				&& $termObject
				&& $enrollment
				&& $instructorObject
			)
		);
		$success = false;
		if ($valid) {
			if (!$courseInstanceObject) {
				$newCi = (
					array_key_exists('src_ci', $_REQUEST) 
						&& $_REQUEST['src_ci'] 
					? $_REQUEST['src_ci'] 
					: NULL
				);
				$courseInstanceObject = new courseInstance($newCi);
			}
			if (!$courseInstanceObject->getDuplicatesByMatch(
				$department, $courseNumber, $section, $termObject->getTermYear(), $termObject->getTermName()
			)){		
				//attempt to create the course instance
				if($courseInstanceObject->createCourseInstance(
					$department, $courseNumber, $providedCourseName, $section, $termObject->getTermYear(), $termObject->getTermName()
				)){	//course created successfully, insert data
					$courseInstanceObject->addInstructor($courseInstanceObject->getPrimaryCourseAliasID(), $instructor);
					$courseInstanceObject->setTerm($termObject->getTermName());
					$courseInstanceObject->setYear($termObject->getTermYear());
					$courseInstanceObject->setActivationDate($activationDate);
					$courseInstanceObject->setExpirationDate($expirationDate);
					$courseInstanceObject->setEnrollment($enrollment);
					$courseInstanceObject->setStatus('ACTIVE');
					
					$newCi = $courseInstanceObject->getCourseInstanceID();
					$success = !is_null($newCi);
				}
			} else {	//duplicates found					
					//display duplicate info
				$errorMessage = 'The course you are attempting to create is already active for this term. Please double-check the department, course number, section, and term of your course.';
			}
		}
		
		if (!$valid || !$success) {
			$this->setModel(array(
				'department' => $department,
				'searchDepartment' => 
					Rd_Array::keyExistsAndNotBlank('searchDepartment', $request) 
					? $request['searchDepartment'] 
					: '',
				'departmentObject' => $departmentObject,
				'section' => $section,
				'courseNumber' => $courseNumber,
				'courseName' => $providedCourseName,
				'term' => $term, //#TODO default to current
				'termObject' => $termObject,
				//#TODO start and end dates...
				'enrollment' => $enrollment, //#TODO default to class constant (open),
				'instructor' => $instructor,
				'searchInstructor' => 
					Rd_Array::keyExistsAndNotBlank('searchInstructor', $request) 
					? $request['searchInstructor'] 
					: '',
				'instructorObject' => $instructorObject,
				'submitted' => $submitted
			));
			if ('' != trim($errorMessage)) {
				$this->addToModel('msg', $errorMessage);
			}
		} else {
			if (Rd_Array::keyExistsAndNotBlank('successCmd', $request)) {
				$this->_delegateManager = Rd_Dispatch::getManager($request['successCmd'], $request());
			} else {
				$this->_setLocation('new class created');
				$this->displayFunction = 'displayCreateSuccess';
				$this->setModel(array('ci' => $newCi));
			}
		}
	}
	
	public function editClassAction($request = array())
	{
		$this->_setLocation('edit class');
		//$this->_withOptions[] = 'quickView';
		Rd_Help::setDefaultArticleId(23);
		
		/*if(!array_key_exists('ci', $request)) {	//get ci
			//get array of CIs (ignored for staff)
			$courses = $this->_user->getCourseInstancesToEdit();					
			$this->displayFunction = 'displaySelectClass';					
			$this->argList = array('editClass', $courses, 'Select class to edit', $request);
			return;
		}*/
		if (!Rd_Array::keyExistsAndNotBlank('ci', $request)) {
			$this->with('960css');
			$this->with('jQueryUiAutocomplete');
			$this->with('noPrototype');
			$returnUrl = (
				array_key_exists('referer', $request)
				? $request['referer']
				: $_SERVER['HTTP_REFERER']
			);
			$hiddenFields = array();
			$courseList =
				Account_Rd::atLeastStaff()
				? (
					Rd_Course::pickerSearchReady($request)
					? Rd_Course::pickerSearch($request)
					: array()
				) : Rd_Course::coursesUserCanEdit($this->_user); //#TODO #RD2.2 implement this.
			$model = array(
				'showSearch' => Account_Rd::atLeastStaff(),
				'formCommand' => 'editClass',
				'returnUrl' => $returnUrl,
				'courses' => $courseList, 
				'hiddenFields' => $hiddenFields,
				'termValue' => (array_key_exists('searchTerm', $request) ? $request['searchTerm'] : ''),
				'instructorFieldValue' => (array_key_exists('searchInstructor', $request) ? $request['searchInstructor'] : ''),
				'instructorValue' => (array_key_exists('searchInstructorResult', $request) ? $request['searchInstructorResult'] : ''),
				'departmentFieldValue' => (array_key_exists('searchDepartment', $request) ? $request['searchDepartment'] : ''),
				'courseFieldValue' => (array_key_exists('searchCourse', $request) ? $request['searchCourse'] : '')
			);
			if (array_key_exists('item', $_REQUEST)) {
				$model['item'] = $_REQUEST['item'];
			}
			if (count($courseList) == 0) {
				$model['noResultsMessage'] = 
					Account_Rd::atLeastStaff() 
					? (Rd_Course::pickerSearchReady($request) ? 'No Courses Matched This Search' : NULL)
					: 'No Applicable Courses To Select';
			}
			$this->setModel($model);
			$this->displayFunction = 'displayCoursePicker';
			return;
		}

		$ci = new courseInstance($request['ci']);	
	
		//update class status
		if(isset($request['updateClassStatus'])) {
			if(!empty($request['status'])) {
				$ci->setStatus($request['status']);
			}
		}
		//update class dates
		if(isset($request['updateClassDates'])) {
			//if not empty, set activation and expiration dates
			//try to convert dates to proper format
			if(!empty($request['activation'])) {
				$ci->setActivationDate($request['activation'], $this->user->getRole());
			}
			if(!empty($request['expiration'])) {
				$ci->setExpirationDate($request['expiration'], $this->user->getRole());
			}
		}
		//change enrollment type
		if(isset($request['setEnrollment'])) {
			$ci->setEnrollment($request['enrollment']);					
		}
		//add/remove/approve/deny enrollment for student
		if(isset($request['rollAction'])) {
			//get student list for approve/deny-all
			if($request['student_id']=='all') {
				$roll = $ci->getRoll();
				$students = array();
				foreach($roll as $courseRoll) { // each possible course
					foreach($courseRoll['PENDING'] as $student) {   //just need the pending students
						$students[] = $student->getUserID();    //just need IDs
					}
				}
			}
			else {	//single-student action
				$students = array($request['student_id']);
			}
			
			$this->_user->editClassRoll($ci->getCourseInstanceID(), $students, $request['rollAction']);
		}
		
		//get the tab to show
		$tab = !empty($request['tab']) ? $request['tab'] : null;

		//show screen
		$this->displayFunction = 'displayEditClass';
		$this->argList = array($ci, 'editClass', $tab);
	}
	
	public function editTitleAction ($request = array()) //#TODO deprecate references to this
	{
		$this->editCrossListingsAction($request);
	}
	
	public function editCrossListingsAction ($request) 
	{
		$this->_setLocation('edit title and cross-listings');
		Rd_Help::setDefaultArticleId(29);
		$msg = null;			
		$this->with('960css');
		$this->with('jQueryUiAutocomplete');
		$this->with('noPrototype');
		$courseInstanceObject = new courseInstance($request['ci']);							
		
		if (array_key_exists('crossListings',$request) && is_array($request['crossListings'])) {
			foreach($request['crossListings'] as $ca => $courseData) {
				$courseObject = new course($ca);
				if ($courseObject) {
					$courseObject->setSection($request['crossListings'][$ca]['section']);
					$courseObject->setName($request['crossListings'][$ca]['title']);
					$courseObject->setDepartmentID($request['crossListings'][$ca]['deptId']);
					$courseObject->setCourseNo($request['crossListings'][$ca]['courseNumber']);
				} else {
					Rd_Layout::appendMessage('generalAlert', 'Unable to find one of the requested courses to edit in the database.');
				}
			}
		}
		
		$courseList =
				Account_Rd::atLeastStaff()
				? (
					Rd_Course::pickerSearchReady($request)
					? Rd_Course::pickerSearch($request)
					: array()
				) : Rd_Course::coursesUserCanEdit($this->_user); //#TODO #RD2.2 implement this.
		$disabledCourseAliasList = array();
		$courseInstanceObject->getPrimaryCourse();
		$courseInstanceObject->course->getDepartment();   //$this->department = new department($this->deptID);
		try{
			$courseInstanceObject->getCrossListings();  //load cross listings	
		} catch (Rd_Exception $e) {
			Rd_Debug::out('Some error getting cross-listings... ' . $e->getMessage());
		}	
		foreach($courseList as $course) {
			if ($course->getCourseAliasID() == $courseInstanceObject->getCourseAliasID()) {
				$disabledCourseAliasList[] = $course->getCourseAliasID();
				continue;
			}
			if ($course->isInCrossListing()) {
				$disabledCourseAliasList[] = $course->getCourseAliasID();
				continue;
			}
			foreach($courseInstanceObject->crossListings as $crossListing) {
				if ($course->getCourseAliasID() == $crossListing->getCourseAliasID()) {
					$disabledCourseAliasList[] = $course->getCourseAliasID();
					continue;
				}
			}
		}
		$coursePickerModel = array( 
			'termValue' => Rd_Array::extract('searchTerm', $request, ''),
			'instructorFieldValue' => Rd_Array::extract('searchInstructor', $request, ''),
			'instructorValue' => Rd_Array::extract('searchInstructorResult', $request, ''),
			'departmentFieldValue' => Rd_Array::extract('searchDepartment', $request, ''),
			'courseFieldValue' => Rd_Array::extract('searchCourse', $request, ''),
			'courses' => $courseList,
			'disabledCourseAliases' => $disabledCourseAliasList,
			'buttonCommand' => 'addCrossListing',
			'buttonParams' => array('ci' => $request['ci']),
			'buttonLabel' => 'Add as Cross-listed',
			'diabledButtonHint' => '<br/>(Not Applicable)',
			'linkOn' => 'ca',
			'method' => 'post',
			'labelCrossListingParents' => TRUE,
			'buttonLabelPrefix' => 'Add ',
			'showSearch' => Account_Rd::atLeastStaff(),
			'hiddenFields' => array('ci' => $courseInstanceObject->getId()),
			'formCommand' => 'editCrossListings',
			'formTitle' => 'ADD CROSSLISTINGS',
			'inline' => true
		);
		if (!Account_Rd::atLeastStaff()) {
			
			$coursePickerModel['resultsTitle'] = 'ADD CROSSLISTINGS';
		}
		
/*		//Delete xlist 	
		if (isset($request['deleteCrossListings']) 
			&& is_array($request['deleteCrossListing']) 
			&& !empty($request['deleteCrossListing']))
		{
			$courseInstanceObject->removeCrossListing($request['deleteCrossListing']);
			$msg = " Cross-listings Successfully Removed.";
		}
*/
		if (isset($request['updateCrossListing'])) {
			/* commented out by kawashi on 11.12.04 - No longer able to change primary course
			$oldPrimaryCourse = new course($_REQUEST['oldPrimaryCourse']);
			$oldPrimaryCourse->setDepartmentID($_REQUEST['primaryDept']);
			$oldPrimaryCourse->setCourseNo($_REQUEST['primaryCourseNo']);
			$oldPrimaryCourse->setSection($_REQUEST['primarySection']);
			$oldPrimaryCourse->setName($_REQUEST['primaryCourseName']);

			//Set New Primary Course
			$ci->setPrimaryCourseAliasID($_REQUEST['primaryCourse']);
			*/

			$primaryCourse = new course($request['primaryCourse']);
			$primaryCourse->setDepartmentID($request['primaryDept']);
			$primaryCourse->setCourseNo($request['primaryCourseNo']);
			$primaryCourse->setSection($request['primarySection']);
			$primaryCourse->setName($request['primaryCourseName']);

			if ($request['cross_listings'])
			{
				$cross_listings = array_keys($request['cross_listings']);
				foreach ($cross_listings as $cross_listing)
				{
					$updateCourse = new course($cross_listing);
					$updateCourse->setDepartmentID($request['cross_listings'][$cross_listing]['dept']);
					$updateCourse->setCourseNo($request['cross_listings'][$cross_listing]['courseNo']);
					$updateCourse->setSection($request['cross_listings'][$cross_listing]['section']);
					$updateCourse->setName($request['cross_listings'][$cross_listing]['courseName']);
				}
				$msg = " Cross-listings Successfully Updated.";
			}
		}


		$deptID = $courseInstanceObject->course->department->getDepartmentID();
				
		if (Account_Rd::lessThanStaff()) {
			$potential_xlistings = $this->_user->fetchCourseInstances('instructor', date('Y-m-d'), date('Y-m-d'), 'ACTIVE');
		} else {
			$potential_xlistings = array();
		}
		$this->displayFunction = 'displayEditCrosslistings';
		$this->setModel(array(
			'ci' => $courseInstanceObject,
			'deptId' => $deptID,
			'msg' => $msg,
			'potentialCrossListings' => $potential_xlistings,
			'coursePickerModel' => $coursePickerModel
		));
		//$this->argList = array($cmd, $ci, $deptID, $msg, $potential_xlistings);
	}
	
	public function uncrossListClassAction ($request = array())
	{
		$ca = Rd_Course_Alias::getById(Rd_Array::extractIfArray('ca', $request, NULL));
		if ($ca) {
			$oldCi = $ca->getCourseInstance();
			if ($ca->isInCrossListing()) {
				if ($ca->uncrossList()) {
					$newCi = $ca->getCourseInstance();
					$this->displayFunction = 'uncrossListClassSuccess';
					$this->setModel(array('ca' => $ca, 'oldCi' => $oldCi, 'newCi' => $newCi));
				} else {
					throw new Rd_Exception_Support('Unable to remove the selected section from the crosslisting.');
				}
			} else {
				$this->displayFunction = 'uncrossListClassSuccess';
				$this->setModel(array('ca' => $ca, 'oldCi' => $oldCi));
			}
		} else {
			throw new Rd_Exception_Support('Unable to find the selected section in the database.');
		}
	}
	
	public function makePrimaryCrossListingAction ($request = array()) 
	{
		$newPrimaryCa = Rd_Course_Alias::getById(Rd_Array::extract('ca', $request, NULL));
		$ci = Rd_Course_Instance::getById(Rd_Array::extract('ci', $request, NULL));
		if ($ci && $ci->getPrimaryCourseAliasID()) {
			$this->displayFunction = 'makePrimaryCrossListingSuccess';
			$this->setModel(array(array('ci' => $ci)));
		}
		if ($ci && $newPrimaryCa && $ci->unCouch()->course->hasCrossListing($newPrimaryCa->getCourseAliasID())) {
			if ($newPrimaryCa->makePrimary()) {
				$this->displayFunction = 'makePrimaryCrossListingSuccess';
				$this->setModel(array('ci' => $ci));
			} else {
				throw new Rd_Exception_Support('Failed to make the selected section the primary section for the cross-listing group.');
			}
		} else {
			throw new Rd_Exception_Support('The selected section is not in the group of cross-listed classes. It must be added before being made the primary for the group.');
		}
	}
	
	public function addCrossListingAction ($request = array())
	{
		$newCa = Rd_Course_Alias::getById(Rd_Array::extract('ca', $request, NULL));
		$ci = Rd_Course_Instance::getById(Rd_Array::extract('ci', $request, NULL));
		if ($ci && $newCa) {
			if ($newCa->isInCrossListing()) {
				throw new Rd_Exception_Support('The selected section to add is already cross-listed under another course, it must be removed from that cross-listing first.'); //#TODO handle this anyway?
			}
			if ($newCa->hasReserves() && !Rd_Array::keyExistsAndNotBlank('confirm', $request)) {
				$this->displayFunction = 'addCrossListingConfirm';
				$this->setModel(array('ci' => $ci, 'ca' => $newCa, 'confirmMessage' => 'The selected section to add has reserves. If you add this section to the cross-listing, it\'s reserves will be deleted. You should copy any reserves you wish to keep from the course before continuing.'));
				return;
			}
			if (!$newCa->addToCrosslisting($ci->getId())) {
				throw new Rd_Exception_Support('Unable to add the selected section to to the cross-listing group.');
			}
			$this->displayFunction = 'addCrossListingSuccess';
			$ci->getPrimaryCourse();
			$this->setModel(array('ci' => $ci, 'ca' => $newCa));
		} else {
			throw new Rd_Exception_Support('The selected ' . ($ci ? 'cross-listing group' : 'section to add') . ' was not found in the database.');
		}
	}
	
	public function deleteClassAction ($request = array()) {
		$this->_setLocation('delete class');
		$courseInstance = NULL;
		if (array_key_exists('ci', $request)) {
			$courseInstance = new courseInstance($request['ci']);
			$courseInstance->getPrimaryCourse();
			$courseInstance->getInstructors();
		} else if (array_key_exists('ca', $request)) {
			$course = new course($request['ca']);
			$courseInstance = $course->getCourseInstance();
			$courseInstance->getPrimaryCourse();
			$courseInstance->getInstructors();
		}
		if ($courseInstance && !Rd_Array::keyExistsAndNotBlank('confirm', $request)){
			$this->_setLocation('confirm delete class');
			$this->displayFunction = 'displayConfirmDelete';
			//$this->argList = array($courseInstance);
			$this->setModel(array('ci' => $courseInstance));
			return;
		} else if ($courseInstance) {
			//#TODO verify the user is allowed to delete this particular course...
			$this->_setLocation('delete class');
			$courseInstance->getPrimaryCourse();
			$courseInstance->destroy();
			$this->displayFunction = 'displayDeleteSuccess';
			$this->argList = array($courseInstance);
		} else {
			if (Account_Rd::atLeastStaff()) {
				$this->displayFunction = 'displayDeleteClass';
				$this->argList = array('deleteClass', $this->_user, $request);
				return;
			}
			throw new Rd_Exception_Support('No course has been selected');
		}
	}	
}

